Add -help-json flag for machine-readable CLI help#7198
Open
ewels wants to merge 12 commits into
Open
Conversation
✅ Deploy Preview for nextflow-docs-staging canceled.
|
Adds a global `-help-json` flag to the Nextflow CLI that prints the current command's help, usage and options as JSON, plus an index of all available commands at the root level. This lets tools and LLMs discover the CLI without scraping the rendered `-help` text. A new `CliSchema` class introspects the JCommander `@Parameter` / `@Parameters` annotations to build the schema. A tip pointing at the flag is added to the main usage screen. Signed-off-by: Phil Ewels <phil.ewels@seqera.io> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
Signed-off-by: Phil Ewels <phil.ewels@seqera.io> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
christopher-hakkaart
left a comment
Collaborator
There was a problem hiding this comment.
Minor language suggestions.
Co-authored-by: Chris Hakkaart <chris.hakkaart@seqera.io> Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
ewels
added a commit
to ewels/rich-click
that referenced
this pull request
Jun 8, 2026
Each subcommand entry now carries a one-line `help` (plus `aliases` and a nested `subcommands` index where present) instead of being a bare names-only tree, so an agent can see what each subcommand does and pick where to drill without a round-trip. This also aligns the entry shape with the sibling `-help-json` feature in Nextflow (nextflow-io/nextflow#7198), so a single consumer can parse both. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Previously hidden options were excluded from the machine-readable schema. Keep them but flag each with `hidden: true`, matching the sibling rich-click --help-json so a single consumer sees the same contract from both. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
Commands that group sub-commands (auth, fs, lineage, module, secrets) now describe them recursively under the `subcommands` key, so a single -help-json call covers the whole command tree. JCommander-backed sub-commands (module) get full option/argument detail; manually-parsed ones surface a name + description index. Adds a SubcommandAware interface that these commands implement, and getDescription() on the auth/secrets sub-command interfaces so their help text has a single source of truth. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
Member
Author
|
New commits were to add recursive listing of all subcommands and their help (not their full usage, to keep context usage minimal). Just the help texts show, allowing the agent to jump straight to the nested subcommand it needs.
|
The tip pointing users at -help-json was only printed on the top-level usage; every sub-command help screen omitted it despite the tip claiming it applies to 'any command'. Centralise the message in a shared Launcher.HELP_JSON_TIP constant and emit it from the leaf-command (JCommander) path and each UsageAware container command. Also drop the redundant 'as JSON' since the flag name already names the format. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
The top-level -help-json now recurses through the whole command tree
(including nested sub-commands like 'module create'), but carries only
names + help text - the map of the CLI. Full option/argument detail is
still disclosed by drilling into a command, keeping progressive
disclosure intact.
Output is rendered by a small width-aware formatter instead of
JsonOutput.prettyPrint: it stays valid, human-readable JSON but condenses
any object or array that fits within ~100 columns onto a single line, so
a leaf node prints as {"help": "..."} rather than across many lines.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
Raise the compact renderer's soft line-length budget from 100 to 160 columns, so each option entry typically prints on a single line. Update docs/cli.md to describe the current behaviour: the top-level index is recursive (the whole command tree by name + description), the progressive-disclosure split between the lightweight root map and full detail on drill-in, and that hidden options are included but flagged with "hidden": true. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
PR #7197 made CmdPlugin a UsageAware command with its own usage rendering, which bypassed the -help-json tip that every other command help screen shows. Restore it, and make CmdPlugin SubcommandAware so its statically-known sub-commands (install, create) are surfaced in -help-json - both at the root index and under 'nextflow plugin -help-json' - matching the human help added in #7197. The dynamic <plugin-name>:<command> form is resolved at runtime and stays out. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Coding agents and tooling increasingly drive the Nextflow CLI, but the only machine interface to it today is the rendered
-helptext. Scraping that output is brittle: it's formatted for humans, wraps to the terminal width, and changes layout without notice. An LLM (or any tool) wanting to know "what flags doesnextflow runtake, and what type is each one?" has to parse prose.This adds a structured, stable contract for that question. It's a direct port of the idea in nf-core/tools#4310, which added
--help-jsonto the nf-core CLI for the same reason — so agents can discover the CLI reliably one command at a time, rather than pulling the whole tree into context or guessing from help text.The design follows the same principles as the nf-core PR:
nextflow -help-jsonreturns the global options plus a recursive index of the whole command tree by name + description (including nested sub-commands likemodule create) — the map of the CLI, without the detail. Drilling into a command (nextflow run -help-json) returns that command's full option/argument detail. Agents see the whole shape up front, then load detail only where they need it.CliSchemaclass reads the JCommander@Parameter/@Parametersannotations directly — the same source of truth that drives-help— so the JSON can't drift from the real CLI.-helpscreen (top-level and each sub-command) points tools and agents at the flag.The flag is marked as a
help-style option, so it works even when required arguments are missing (just like-help).What it looks like
nextflow -help-json— global options + a recursive name/description index of the whole tree (no per-command detail; just the map):Full
nextflow -help-jsonoutput{ "name": "nextflow", "path": "nextflow", "usage": "nextflow [options] COMMAND [arg...]", "params": [ {"name": "config", "kind": "option", "type": "List", "opts": ["-C"], "help": "Use the specified configuration file(s) overriding any defaults"}, {"name": "jvmOpts", "kind": "option", "type": "Map", "opts": ["-D"], "help": "Set JVM properties"}, {"name": "background", "kind": "option", "type": "boolean", "opts": ["-bg"], "help": "Execute nextflow in background", "is_flag": true}, {"name": "userConfig", "kind": "option", "type": "List", "opts": ["-c", "-config"], "help": "Add the specified file to configuration set"}, { "name": "ignoreConfigIncludes", "kind": "option", "type": "boolean", "opts": ["-config-ignore-includes"], "help": "Disable the parsing of config includes", "is_flag": true }, {"name": "debug", "kind": "option", "type": "List", "opts": ["-debug"], "hidden": true}, {"name": "logFile", "kind": "option", "type": "String", "opts": ["-log"], "help": "Set nextflow log file path"}, {"name": "quiet", "kind": "option", "type": "boolean", "opts": ["-q", "-quiet"], "help": "Do not print information messages", "is_flag": true}, { "name": "remoteDebug", "kind": "option", "type": "boolean", "opts": ["-remote-debug"], "help": "Enable JVM interactive remote debugging (experimental)", "is_flag": true }, { "name": "selfUpdate", "kind": "option", "type": "boolean", "opts": ["-self-update"], "help": "Update nextflow to the latest version", "is_flag": true, "hidden": true }, {"name": "syslog", "kind": "option", "type": "String", "opts": ["-syslog"], "help": "Send logs to syslog server (eg. localhost:514)"}, { "name": "trace", "kind": "option", "type": "List", "opts": ["-trace"], "help": "Enable trace level logging for the specified package name - multiple packages can be provided separating them with a comma e.g. '-trace nextflow,io.seqera'" }, {"name": "version", "kind": "option", "type": "boolean", "opts": ["-v", "-version"], "help": "Print the program version", "is_flag": true} ], "subcommands": { "auth": { "help": "Manage Seqera Platform authentication", "subcommands": { "config": {"help": "Configure Seqera Platform settings"}, "login": {"help": "Authenticate with Seqera Platform"}, "logout": {"help": "Remove authentication and revoke access token"}, "status": {"help": "Show current authentication status and configuration"} } }, "clean": {"help": "Clean up project cache and work directories"}, "clone": {"help": "Clone a project into a folder"}, "config": {"help": "Print a project configuration"}, "console": {"help": "Launch Nextflow interactive console"}, "drop": {"help": "Delete the local copy of a project"}, "fs": { "help": "Perform filesystem operations", "subcommands": { "cat": {"help": "Print a file to the stdout"}, "cp": {"help": "Copy a file"}, "ls": {"help": "List the content of a folder"}, "mv": {"help": "Move a file"}, "rm": {"help": "Remove a file"}, "stat": {"help": "Print file to meta info"} } }, "help": {"help": "Print the usage help for a command"}, "info": {"help": "Print project and system runtime information"}, "inspect": {"help": "Inspect process settings in a pipeline project"}, "kuberun": {"help": "Execute a workflow in a Kubernetes cluster (experimental)"}, "launch": {"help": "Launch a workflow in Seqera Platform"}, "lineage": { "help": "Explore workflows lineage metadata", "subcommands": { "check": {"help": "Checks the integrity of an lineage file path"}, "diff": {"help": "Show differences between two lineage descriptions"}, "find": {"help": "Find lineage metadata descriptions matching with a query"}, "list": {"help": "List the executions with lineage enabled"}, "render": {"help": "Render the lineage graph for a workflow output"}, "view": {"help": "Print the description of a Lineage ID (lid)"} } }, "lint": {"help": "Lint Nextflow scripts and config files"}, "list": {"help": "List all downloaded projects"}, "log": {"help": "Print executions log and runtime info"}, "logfile": {"help": "Print the contents of a Nextflow log file"}, "module": { "help": "Manage Nextflow modules", "subcommands": { "create": {"help": "Create a new module skeleton"}, "install": {"help": "Install a module from the registry"}, "list": {"help": "List all installed modules"}, "publish": {"help": "Publish a module to the registry"}, "remove": {"help": "Remove an installed module"}, "run": {"help": "Run a module directly from the registry"}, "search": {"help": "Search for modules in the registry"}, "spec": {"help": "Generate a meta.yml spec for a local module"}, "validate": {"help": "Validate a module structure and metadata"}, "view": {"help": "Show module information and usage template"} } }, "plugin": { "help": "Execute plugin-specific commands", "subcommands": {"create": {"help": "Create a new plugin project from the template"}, "install": {"help": "Install a plugin"}} }, "pull": {"help": "Download or update a project"}, "run": {"help": "Execute a pipeline project"}, "secrets": { "help": "Manage pipeline secrets", "subcommands": { "delete": {"help": "Delete an entry from the secrets store"}, "get": {"help": "Get a secret value with the name"}, "list": {"help": "List all names in the secrets store"}, "set": {"help": "Set a key-pair in the secrets store"} } }, "self-update": {"help": "Update nextflow runtime to the latest available version"}, "view": {"help": "View project script file(s)"} } }nextflow info -help-json— a single command's full detail (options first, arguments last; the hidden-ddis surfaced with a flag rather than dropped). Output is condensed: entries that fit within ~160 columns stay on one line (seeargs), and only longer ones expand:{ "name": "info", "path": "nextflow info", "usage": "nextflow info [options] [args...]", "params": [ {"name": "detailed", "kind": "option", "type": "boolean", "opts": ["-d"], "help": "Show detailed information", "is_flag": true}, {"name": "moreDetailed", "kind": "option", "type": "boolean", "opts": ["-dd"], "is_flag": true, "hidden": true}, {"name": "format", "kind": "option", "type": "String", "opts": ["-o"], "help": "Output format, either: text (default), json, yaml"}, {"name": "checkForUpdates", "kind": "option", "type": "boolean", "opts": ["-u", "-check-updates"], "help": "Check for remote updates", "is_flag": true}, {"name": "args", "kind": "argument", "type": "List", "help": "project name"} ], "help": "Print project and system runtime information" }The flag is discoverable from the normal human-readable help. A one-line tip is appended to every
-helpscreen — the top-level usage and each sub-command:Notes
-h,-help,-help-json) are excluded from the reported parameters. Hidden options are included but flagged with"hidden": true(e.g.info's-dd), so tools can choose to surface or ignore them.module create,lineage view) but carries only names + help text — no params, aliases or paths. Full option/argument detail is disclosed by drilling into a command, e.g.nextflow module -help-json, which reportsmodule's own options plus the full detail of each nested sub-command.pluginlists its statically-known sub-commands (install,create); its dynamic<plugin-name>:<command>calls are resolved at runtime and can't be introspected.{"help": "..."}rather than spread across several lines.CliSchemaTestcover the root schema, a command schema, and alias surfacing. ExistingLauncherTesttests still pass.🤖 Generated with Claude Code